/*
� 最佳准确率窗口:
{
  windowSize: 174,
  total: 1244,
  correct: 822,
  accuracy: 66.08,
  maxWrongStreak: 7
}

� 最小连续错误窗口:
{
  windowSize: 97,
  total: 1244,
  correct: 791,
  accuracy: 63.59,
  maxWrongStreak: 5
}
*/
// 📦 引入工具库
const _ = require("lodash");
const fs = require("fs");
const path = require("path");

// 📦 ESM 支持模块加载
const esm = require("esm");
const requireModule = esm(module);

// 📦 项目依赖模块
const { readAllValues } = requireModule(
  "../../../awakened-potential/helpers/readAllValues.js"
);
const checkAccuracy = requireModule("../../utils/checkAccuracy.js");

// ✅ 读取历史开奖数据（模拟全部）
const allValues = readAllValues("m");

// ✅ 号码池（01 ~ 49）
const allNumbers = Array.from({ length: 49 }, (_, i) =>
  (i + 1).toString().padStart(2, "0")
);

/**
 * 分析当前窗口内的周期评分：
 * - 距离上次出现的间隔越稳定 → 得分越高
 */
function getCycleScoreMap(temp) {
  const lastSeen = {};
  const intervalMap = {};

  temp.forEach((item, idx) => {
    const num = item.number;
    if (lastSeen[num] !== undefined) {
      const interval = idx - lastSeen[num];
      if (!intervalMap[num]) intervalMap[num] = [];
      intervalMap[num].push(interval);
    }
    lastSeen[num] = idx;
  });

  const scoreMap = {};
  allNumbers.forEach((num) => {
    const gaps = intervalMap[num];
    if (!gaps || gaps.length < 2) {
      scoreMap[num] = 0;
    } else {
      const mean =
        gaps.reduce((sum, g) => sum + g, 0) / gaps.length;
      const variance =
        gaps.reduce((sum, g) => sum + Math.pow(g - mean, 2), 0) / gaps.length;
      scoreMap[num] = variance === 0 ? 999 : 1 / variance;
    }
  });

  return scoreMap;
}

/**
 * 选出 32 个分数最高的号码
 */
function select32NumbersByCycle(temp) {
  const scoreMap = getCycleScoreMap(temp);
  const sorted = Object.entries(scoreMap)
    .sort((a, b) => b[1] - a[1]) // 分数从高到低
    .slice(0, 32)
    .map(([num]) => num);

  if (sorted.length !== 32) {
    throw new Error("❌ 选出号码不足 32 个！");
  }

  return sorted;
}

/**
 * 多窗口遍历
 */
const results = [];

for (let windowSize = 2; windowSize <= 200; windowSize++) {
  let correct = 0;
  let maxWrongStreak = 0;
  let currentWrongStreak = 0;
  const predictResults = [];

  allValues.forEach((item, index) => {
    const temp = allValues.slice(Math.max(0, index - windowSize), index);
    if (!temp.length) return;

    const predicted = select32NumbersByCycle(temp);
    const isHit = checkAccuracy(predicted, item.number);

    if (isHit) {
      correct++;
      currentWrongStreak = 0;
    } else {
      currentWrongStreak++;
      maxWrongStreak = Math.max(maxWrongStreak, currentWrongStreak);
    }

    predictResults.push(predicted);
  });

  const total = predictResults.length;
  const accuracy = total ? ((correct / total) * 100).toFixed(2) : 0;

  results.push({
    windowSize,
    total,
    correct,
    accuracy: Number(accuracy),
    maxWrongStreak,
  });
}

// ✅ 输出结果汇总
results.forEach((r) => {
  console.log(
    `windowSize = ${r.windowSize}, 准确率 = ${r.accuracy}%, 最大连续错误 = ${r.maxWrongStreak}`
  );
});

// ✅ 输出最优解
const bestAcc = _.maxBy(results, "accuracy");
const bestStable = _.minBy(results, "maxWrongStreak");

console.log("\n🏆 最佳准确率窗口:");
console.log(bestAcc);

console.log("\n🧱 最小连续错误窗口:");
console.log(bestStable);
